package com.feng.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feng.constants.SystemConstants;
import com.feng.domain.ResponseResult;
import com.feng.domain.dto.AddRoleDto;
import com.feng.domain.dto.AdminUpdateRoleStatusDto;
import com.feng.domain.dto.UpdateRoleDto;
import com.feng.domain.entity.Menu;
import com.feng.domain.entity.RoleMenu;
import com.feng.domain.vo.AdminRoleListVo;
import com.feng.domain.vo.ArticleListPageVo;
import com.feng.domain.vo.ListAllRoleVo;
import com.feng.domain.vo.RoleGetIdVo;
import com.feng.mapper.RoleMapper;
import com.feng.domain.entity.Role;
import com.feng.mapper.RoleMenuMapper;
import com.feng.service.RoleMenuService;
import com.feng.service.RoleService;
import com.feng.utils.BeanCopyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 角色信息表(Role)表服务实现类
 *
 * @author makejava
 * @since 2023-04-20 00:18:01
 */
@Service()
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Override
    public List<String> selectRoleByUserId(Long id) {
        //如果id为1就返回直接admin
        if(id == 1L){
            List<String> role = new ArrayList<>();
            role.add("admin");
            return role;
        }

        List<String> role = getBaseMapper().selectRoleByUserId(id);
        return role;
    }

    @Override
    public ResponseResult getList(Integer pageNum, Integer pageSize, String roleName, String status) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(roleName), Role::getRoleName, roleName);
        wrapper.eq(StringUtils.hasText(status), Role::getStatus, status);
        wrapper.orderByAsc(Role::getRoleSort);
        Page<Role> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page(page, wrapper);
        List<AdminRoleListVo> adminRoleListVo = BeanCopyUtil.articleListVo(page.getRecords(), AdminRoleListVo.class);
        ArticleListPageVo pageVo = new ArticleListPageVo(adminRoleListVo, page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult updateRoleStatus(AdminUpdateRoleStatusDto statusDto) {
        LambdaUpdateWrapper<Role> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Role::getId, statusDto.getRoleId());
        wrapper.set(Role::getStatus, statusDto.getStatus());
        update(wrapper);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult addRole(AddRoleDto addRoleDto) {
        Role role = BeanCopyUtil.articleVo(addRoleDto, Role.class);
        save(role);
        if(!addRoleDto.getMenuIds().isEmpty()){
            List<RoleMenu> roleMenus = addRoleDto.getMenuIds().stream().parallel()
                    .map(menuId -> new RoleMenu(role.getId(), menuId))
                    .collect(Collectors.toList());
            roleMenuService.saveBatch(roleMenus);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getRole(Long id) {
        Role role = getById(id);
        RoleGetIdVo roleGetIdVo = BeanCopyUtil.articleVo(role, RoleGetIdVo.class);
        return ResponseResult.okResult(roleGetIdVo);
    }

    @Transactional
    @Override
    public ResponseResult updateRole(UpdateRoleDto updateRoleDto) {
        Role role = BeanCopyUtil.articleVo(updateRoleDto, Role.class);
        updateById(role);
        LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenu::getRoleId, updateRoleDto.getId());
        roleMenuMapper.delete(wrapper);
        if(!updateRoleDto.getMenuIds().isEmpty()){
            List<RoleMenu> roleMenus = updateRoleDto.getMenuIds().stream().parallel()
                    .map(roleId -> new RoleMenu(updateRoleDto.getId(), roleId))
                    .collect(Collectors.toList());
            roleMenuService.saveBatch(roleMenus);
        }
        return ResponseResult.okResult();
    }

    @Transactional
    @Override
    public ResponseResult delRole(List<Long> ids) {
        getBaseMapper().deleteBatchIds(ids);
        for(Long id: ids){
            LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RoleMenu::getRoleId, id);
            roleMenuMapper.delete(wrapper);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult listAllRole() {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getStatus, SystemConstants.STATUS_NORMAL);
        List<Role> roles = list(wrapper);
        List<ListAllRoleVo> listAllRoleVo = BeanCopyUtil.articleListVo(roles, ListAllRoleVo.class);
        return ResponseResult.okResult(listAllRoleVo);
    }
}

